LibManager = {}

local File = luajava.bindClass "java.io.File"
local Http = luajava.bindClass "com.androlua.Http"
local Build = luajava.bindClass "android.os.Build"
local Process = luajava.bindClass "android.os.Process"
local VERSION = luajava.bindClass "android.os.Build$VERSION"
local LuaApplication = luajava.bindClass "com.androlua.LuaApplication"

local LIB_DIR = LuaApplication.getInstance().getLibDir()
File(LIB_DIR).mkdirs()


function LibManager.check(libName)
  return pcall(require, libName)
end

function LibManager.getAbi()
  local is64BitProcess = (VERSION.SDK_INT >= 23 and Process.is64Bit()) or
  (Build.CPU_ABI and string.find(Build.CPU_ABI, "64"))
  local deviceAbis = (VERSION.SDK_INT >= 21 and Build.SUPPORTED_ABIS) or { Build.CPU_ABI }
  if not deviceAbis or #deviceAbis == 0 then deviceAbis = { Build.CPU_ABI } end

  for i = 0, #deviceAbis do
    local abi = deviceAbis[i]
    if abi and ((string.find(abi, "64") ~= nil) == is64BitProcess) then
      return abi
    end
  end

  return deviceAbis[0] or Build.CPU_ABI
end

function LibManager.require(baseUrls, libName, callback)
  local finalLibPath = string.format("%s/lib%s.so", LIB_DIR, libName)
  local file = File(finalLibPath)
  if file.exists() then
    local expireDays = 3
    local expireMillis = expireDays * 86400000
    local age = os.time() * 1000 - file.lastModified()
    if age > expireMillis then
      file.delete()
    end
  end
  
  local hasLib, lib = LibManager.check(libName)
  if hasLib then
    _G[libName] = lib
    if callback then callback(true) end
    return
  end

  if type(baseUrls) == "string" then baseUrls = { baseUrls } end
  if not baseUrls or #baseUrls == 0 then
    if callback then callback(false, "错误: 未提供任何下载节点 URL。") end
    return
  end

  local function tryDownload(urlIndex)
    if urlIndex > #baseUrls then
      File(finalLibPath).delete()
      if callback then callback(false, "所有下载节点均下载失败。") end
      return
    end

    local baseUrl = baseUrls[urlIndex]:gsub("/$", "")
    local abi = LibManager.getAbi()
    if not abi then
      if callback then callback(false, "未能确定当前设备兼容的 ABI。") end
      return
    end

    local downloadUrl = string.format("%s/%s/%s/lib%s.so", baseUrl, libName, abi, libName)
    local hostName = string.match(baseUrl, "//([^/]+)") or baseUrl
    local simpleFileName = "lib" .. libName .. ".so"

    --print(string.format("正在尝试从 %s #%d 下载: %s", hostName, urlIndex, simpleFileName))

    Http.download(downloadUrl, finalLibPath, function(code)
      if code ~= 200 then
        --print(string.format("%s #%d 下载%s失败 (错误码: %d)", hostName, urlIndex, simpleFileName, code))
        tryDownload(urlIndex + 1)
        return
      end

      local success, err_msg = xpcall(function()
        local loadedLib = require(libName)
        if not loadedLib then error("require() 失败, 文件可能已损坏") end
        _G[libName] = loadedLib
      end, function(err)
        File(finalLibPath).delete()
        return "加载库失败: " .. tostring(err)
      end)

      if callback then
        if success then callback(true) else callback(false, err_msg) end
      end
    end)
  end

  tryDownload(1)
end